package com.lijie.ljblog.chess;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lijie.ljblog.enums.ChessColorEnum;
import com.lijie.ljblog.model.Person;
import com.lijie.ljblog.model.vo.MatchResponseVO;
import com.lijie.ljblog.service.PersonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author lijie
 * @Date 2022/10/25 18:59
 **/
@Component
@Slf4j
public class GameMatch {
    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private RoomManager roomManager;
    @Autowired
    private PersonService personService;

    private final ObjectMapper objectMapper = new ObjectMapper();

    //游戏玩家匹配队列
    private final Queue<Person> normalQueue = new ConcurrentLinkedQueue<>();

    public void add(Integer userId) {

        Person user =personService.getById(userId);
        if(ObjectUtils.isEmpty(user)){
            throw new RuntimeException("未查找到玩家id");
        }
        synchronized (normalQueue){
            normalQueue.offer(user);
            normalQueue.notifyAll();
            log.info("玩家" + user.getUserName() + "进入排队");
        }
    }


    public void remove(Integer userId) {
        Person user = personService.getById(userId);
        if(ObjectUtils.isEmpty(user)){
            throw new RuntimeException("未查找到玩家id");
        }
        synchronized (normalQueue){
            normalQueue.remove(user);
            log.info("玩家" + user.getUserName() + "退出排队");
        }
    }

    /**
     * 判断用户id是否已经在匹配队列中
     * @param userId
     * @return
     */
    public boolean checkUserOnQueue(Integer userId){
        List<Person> collect = normalQueue.stream().filter(e -> e.getId().equals(userId)).collect(Collectors.toList());
        return  !collect.isEmpty();
    }

    //启动三个线程循环调用各自的队列
    public GameMatch(){
        new Thread(){
            @Override
            public void run() {
                while(true){
                    handlerMatch();
                }
            }
        }.start();
    }

    private void handlerMatch(){
        synchronized (this.normalQueue){
            try{
                //五子棋需要两个人，当队列中人数少于2时等待
                while(this.normalQueue.size() < 2){
                    this.normalQueue.wait();
                }
                Person user1 = this.normalQueue.poll();
                Person user2 = this.normalQueue.poll();

                assert user2 != null;
                log.info("匹配出两个玩家" + user1.getUserName() +" " + user2.getUserName());
                WebSocketSession session1 = onlineUserManager.getGameHallSession(user1.getId());
                WebSocketSession session2 = onlineUserManager.getGameHallSession(user2.getId());
                if(session1 == null){
                    this.normalQueue.offer(user2);
                    return;
                }
                if(session2 == null){
                    this.normalQueue.offer(user1);
                    return;
                }
                //防止多开
                if (session1 == session2){
                    this.normalQueue.add(user1);
                }


                ChessGameRoom room = new ChessGameRoom();
                //随机先后手
                int i=new Random().nextInt(2);
                Map<Integer, ChessColorEnum> playerColor = room.getPlayerColor();
                if(0==i){
                    playerColor.put(user1.getId(), ChessColorEnum.CHESS_POINT_BLACK);
                    playerColor.put(user2.getId(), ChessColorEnum.CHESS_POINT_WHITE);
                }else{
                    playerColor.put(user2.getId(), ChessColorEnum.CHESS_POINT_BLACK);
                    playerColor.put(user1.getId(), ChessColorEnum.CHESS_POINT_WHITE);
                }
                //设置对手map，以便使用
                Map<Integer, Person> personMap = room.getOpponent();
                personMap.put(user1.getId(), user2);
                personMap.put(user2.getId(), user1);

                // 将两个玩家加入对战房间
                roomManager.add(user1.getId(),user2.getId(),room);


                //给玩家1发送匹配成功的信息
                MatchResponseVO response1 = new MatchResponseVO();
                response1.setOk(true);
                response1.setMessage("MatchSuccess");
                session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response1)));
                //给玩家2发送匹配成功的信息
                MatchResponseVO response2 = new MatchResponseVO();
                response2.setOk(true);
                response2.setMessage("MatchSuccess");
                session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));
            }catch (IOException | InterruptedException e){
                e.printStackTrace();
            }
        }


    }

}
